package com.bingxue.edu.management.education.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.bingxue.edu.framework.common.util.SpringContextHolder;
import com.bingxue.edu.framework.common.util.ValidationUtils;
import com.bingxue.edu.framework.mybatis.base.BaseService;
import com.bingxue.edu.management.education.mapper.ParentMapper;
import com.bingxue.edu.management.education.mapper.StudentMapper;
import com.bingxue.edu.management.education.model.entity.Parent;
import com.bingxue.edu.management.education.model.entity.Student;
import com.bingxue.edu.management.education.model.req.ParentReq;
import com.bingxue.edu.management.education.model.req.ParentUpdateReq;
import com.bingxue.edu.management.education.model.resp.ParentDetailResp;
import com.bingxue.edu.management.event.RecommenderSetEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.bingxue.edu.management.education.model.entity.table.ParentTableDef.PARENT;
import static com.bingxue.edu.management.education.model.entity.table.StudentTableDef.STUDENT;

/**
 * 家长账号实现类
 * @author zq
 * @since 2024/08/19
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ParentService extends BaseService<ParentMapper, Parent> {

    private final StudentMapper studentMapper;

    /**
     * 根据手机号查询家长信息
     * @param phone 家长手机号
     */
    public Parent getByPhone(String phone) {
        return this.queryChain().where(PARENT.MOBILE_PHONE.eq(phone)).one();
    }

    /**
     * 查询家长详情
     * @param id 家长id
     */
    public ParentDetailResp getDetailById(String id) {
        return this.getMapper().selectOneWithRelationsByIdAs(id, ParentDetailResp.class);
    }

    @Transactional(rollbackFor = Exception.class)
    public void create(ParentReq req) {
        Parent parent = this.copy(req);
        //密码加密
        String password = StrUtil.isNotBlank(parent.getPassword()) ? parent.getPassword() : RandomUtil.randomString(8);
        parent.setPassword(DigestUtil.bcrypt(password));
        this.save(parent);
        log.info("创建家长账号成功, {}", parent);
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(ParentUpdateReq req, String id) {
        Parent oldParent = this.getById(id);
        ValidationUtils.throwIfNull(oldParent, "家长信息不存在");
        if (req.getMobilePhone() != null && !oldParent.getMobilePhone().equals(req.getMobilePhone())) {
            //判断是否存在相同手机号
            ValidationUtils.throwIf(this.queryChain().where(PARENT.MOBILE_PHONE.eq(req.getMobilePhone())).exists(),"存在相同手机号,不可修改");

            Student student = new Student();
            student.setParentPhone(req.getMobilePhone());
            // 更改学生手机号码
            studentMapper.updateByCondition(student, true, STUDENT.PARENT_ID.eq(id));
        }
        BeanUtil.copyProperties(req, oldParent, CopyOptions.create().ignoreNullValue());
        //同步修改用户名
        oldParent.setUsername(req.getMobilePhone());
        this.updateById(oldParent);

        log.info("修改家长信息成功: req: {}, id: {}", req, id);
    }

    /**
     * 更新设置推荐人
     */
    public void setRecommender(String parentId, String recommenderPhone) {
        Parent parent = getById(parentId);
        ValidationUtils.throwIfNull(parent, "家长未找到");
        ValidationUtils.throwIfNotEmpty(parent.getRecommender(), "不能重复设置推荐人");
        ValidationUtils.throwIfEqual(parent.getMobilePhone(), recommenderPhone, "不能设置自己为推荐人");
        Parent recommender = this.getByPhone(recommenderPhone);
        ValidationUtils.throwIfNull(recommender, "推荐人手机号不存在，请检查");
        parent.setRecommender(recommenderPhone);
        this.updateById(parent);
        RecommenderSetEvent event = new RecommenderSetEvent(parentId, parent.getMobilePhone(), recommenderPhone);
        SpringContextHolder.publishEvent(event);
        log.info("设置推荐人成功, parentId: {}, recommender: {}", parentId, recommenderPhone);
    }
}
